package whf.framework.log.util;

import javax.servlet.http.HttpServletRequest;

import whf.framework.log.entity.Log;
import whf.framework.log.service.LogService;
import whf.framework.log.service.LogServiceImp;
import whf.framework.meta.MetaFactory;
import whf.framework.resource.thread.AbstractPoolableThread;
import whf.framework.resource.thread.ThreadPool;
import whf.framework.security.entity.User;
import whf.framework.util.StringUtils;
import whf.framework.util.ThreadContext;


/**
 * 记录日志类
 * @author wanghaifeng
 * @create Feb 13, 2007 2:17:24 PM
 * 
 */
public class LogUtil {
	private static whf.framework.log.Log log = whf.framework.log.LogFactory.getLog(LogUtil.class);
	
	private static LogService service;
	
	static{
		try{
			service = LogServiceImp.getLogService();
		} catch (Exception e){
			log.error("LogService load failure!", e);
		}
		log.info("logging thread pool started!");
	}
	
	private LogUtil(){
		
	}
	
	public static void log(HttpServletRequest req, String target, long consumeTime){
		log(req, req.getMethod(), target, req.getQueryString(), consumeTime);
	}
	
	public static void logAccessError(HttpServletRequest req, String operationType, String target, Throwable exception, long consumeTime){
		log(req, operationType, target, StringUtils.getExceptionDetail(exception), consumeTime);
	}
	
	public static void log(HttpServletRequest req, String operationType, String target, String remarks, long consumeTime){
		String operation = req.getParameter("webMethod");
		String params = req.getQueryString();
		User user = ThreadContext.getUserInUserContext();
		String operator = null;
		if(user != null) {
			operator = user.getName() + "(" + user.getUsername() +")";
		}
		String department = null;
		if(user != null && user.getDept() != null) {
			department = user.getDept().getCode();
		}
		String ip = req.getRemoteAddr();
		String sessionId = req.getSession() != null? req.getSession().getId():"";

		whf.framework.log.entity.Log logEntity = new whf.framework.log.entity.Log(department, operator, 
				target, req.getMethod(), operation, params,
				sessionId, ip, consumeTime, null);
		log(logEntity);
	}
	
	public static void log(Log log){
		if(log != null && log.getTarget() != null && log.getTarget().startsWith("whf.framework.log")) return;
		ThreadPool.getDefaultInstance().addThread(new LogThread(log));
	}
	
	static class LogThread extends AbstractPoolableThread{

		private Log logable;
		
		LogThread(Log log){
			this.logable = log;
		}
		
		@Override
		public void onTimeout() {
			log.warn("Log timeout:\n" + logable);
		}
		
		public void run(){
			if(service == null) return;
			ThreadContext.setCurrentMeta(MetaFactory.findByModelClass(Log.class));
			try{
				service.create(logable);
				return;
			}catch(Exception e){
				log.error(this, e);
			}
		}
	}
}
